﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace HeartLess.Core.Input
{
    public class KeyboardInput : IInput
    {
        private KeyboardState _previousKbState;
        private KeyboardState _currentKbState;
        private MouseState _previousMouseState;
        private MouseState _currentMouseState;

        private readonly Keys MOVING_UP_KEY;
        private readonly Keys MOVING_DOWN_KEY;
        private readonly Keys MOVING_LEFT_KEY;
        private readonly Keys MOVING_RIGHT_KEY;
        private readonly Keys BACK_KEY = Keys.Escape;
        private readonly Keys PAUSE_KEY = Keys.Enter;
        private readonly Keys JUMP_KEY = Keys.Space;
        private readonly Keys FIRE_KEY = Keys.LeftShift;

        private bool _allowRepeat;
                
        public KeyboardInput(int playerId)
        {
            if (playerId == 1)
            {
                MOVING_UP_KEY = Keys.W;
                MOVING_DOWN_KEY = Keys.S;
                MOVING_LEFT_KEY = Keys.A;
                MOVING_RIGHT_KEY = Keys.D;
            }
            else
            {
                MOVING_UP_KEY = Keys.Up;
                MOVING_DOWN_KEY = Keys.Down;
                MOVING_LEFT_KEY = Keys.Left;
                MOVING_RIGHT_KEY = Keys.Right;
            }
        }

        void IInput.Initialize()
        {
            _currentKbState = Keyboard.GetState();
            _currentMouseState = Mouse.GetState();
        }

        void IInput.Update(GameTime gameTime)
        {
            _previousKbState = _currentKbState;
            _currentKbState = Keyboard.GetState();

            _previousMouseState = _currentMouseState;
            _currentMouseState = Mouse.GetState();
        }

        bool IInput.IsMovingUp
        {
            get
            {
                if (_allowRepeat)
                {
                    return _currentKbState.IsKeyDown(MOVING_UP_KEY);
                }
                else
                {
                    return _currentKbState.IsKeyDown(MOVING_UP_KEY) &&
                        _previousKbState.IsKeyUp(MOVING_UP_KEY);
                }
            }
        }

        bool IInput.IsMovingDown
        {
            get
            {
                if (_allowRepeat)
                {
                    return _currentKbState.IsKeyDown(MOVING_DOWN_KEY);
                }
                else
                {
                    return _currentKbState.IsKeyDown(MOVING_DOWN_KEY) &&
                        _previousKbState.IsKeyUp(MOVING_DOWN_KEY);
                }
            }
        }

        bool IInput.IsMovingLeft
        {
            get
            {
                if (_allowRepeat)
                {
                    return _currentKbState.IsKeyDown(MOVING_LEFT_KEY);
                }
                else
                {
                    return _currentKbState.IsKeyDown(MOVING_LEFT_KEY) &&
                        _previousKbState.IsKeyUp(MOVING_LEFT_KEY);
                }
            }
        }

        bool IInput.IsMovingRight
        {
            get
            {
                if (_allowRepeat)
                {
                    return _currentKbState.IsKeyDown(MOVING_RIGHT_KEY);
                }
                else
                {
                    return _currentKbState.IsKeyDown(MOVING_RIGHT_KEY) &&
                        _previousKbState.IsKeyUp(MOVING_RIGHT_KEY);
                }
            }
        }
                

        bool IInput.IsPressingPause
        {
            get
            {
                bool currentlyPressing = (_currentKbState.IsKeyDown(PAUSE_KEY));
                bool previouslyReleased = (_previousKbState.IsKeyUp(PAUSE_KEY));

                return (currentlyPressing && previouslyReleased);
            }
        }

        bool IInput.IsPressingSelect
        {
            get
            {
                bool currentlyLeftClicking = (_currentMouseState.LeftButton == ButtonState.Pressed);
                bool previouslyLeftReleased = (_previousMouseState.LeftButton == ButtonState.Released);

                return (currentlyLeftClicking && previouslyLeftReleased);
            }
        }

        bool IInput.IsPressingBack
        {
            get
            {
                bool currentlyPressing = (_currentKbState.IsKeyDown(BACK_KEY));
                bool previouslyPressing = (_previousKbState.IsKeyDown(BACK_KEY));

                return (currentlyPressing && !previouslyPressing);
            }
        }

        bool IInput.IsPressingJump
        {
            get
            {
                bool currentlyPressing = (_currentKbState.IsKeyDown(JUMP_KEY));
                bool previouslyPressing = (_previousKbState.IsKeyDown(JUMP_KEY));

                return (currentlyPressing && !previouslyPressing);
            }
        }

        public bool IsPressingFire
        {
            get
            {
                bool currentlyPressing = (_currentKbState.IsKeyDown(FIRE_KEY));
                bool previouslyPressing = (_previousKbState.IsKeyDown(FIRE_KEY));

                return (currentlyPressing && !previouslyPressing);
            }
        }

        Point IInput.PointerLocation
        {
            get 
            { 
                return new Point(_currentMouseState.X, _currentMouseState.Y); 
            }
        }

        bool IInput.DirectionalRepeatAllowed
        {
            set
            {
                _allowRepeat = value; 
            }
        }
    }
}
